package com.unknowpupil.alibaba.cloud.configure.interceptor;


import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.Charset;
import java.util.Enumeration;

/**
 * 用于设置请求头，传递token
 *
 * @Classname: FeignRequestInterceptor
 * @Author: <a> w10g </a>
 * @CreateDate: Create in 2020/1/4 15:41
 * @Description: feign 全局拦截 封装请求头 与请求体 参数请求体进入feign
 * @Version: 1.0
 */

public class FeignRequestInterceptor implements RequestInterceptor {
    final static Logger log = LoggerFactory.getLogger(FeignRequestInterceptor.class);

    /**
     * 重写Apply方法 拿到一个 RequestTemplate 设置请求头和请求体，拿到httprequest 就可以赋写进去带上token 和头部了
     * @param requestTemplate {@link RequestTemplate}
     */
    @Override
    public void apply(RequestTemplate requestTemplate) {
        log.info("[ feign 拦截器 ] 进入feign 拦截器");
        //feign带的东西
        ServletRequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());

        //断言不为空，为空就报错
        assert attributes != null;
        //得到HttpServletRequest
        HttpServletRequest request = attributes.getRequest();
        log.info("[ feign 拦截器 ] 得到 httpServletRequest={}", request);
        //响应头
        Enumeration<String> headerNames = request.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                String header = request.getHeader(name);
                requestTemplate.header(name, header);
            }
        }
        log.info("[ feign 拦截器 ] 封装响应头 heard={}", requestTemplate.headers());
        //响应体
        Enumeration<String> parameterNames = request.getParameterNames();
        //拼接响应体
        StringBuilder body = new StringBuilder();
        if (parameterNames != null) {
            while (parameterNames.hasMoreElements()) {
                String name = parameterNames.nextElement();
                String value = request.getHeader(name);
                //将令牌放入 Header中
                if ("access_token".equals(name)) {
                    requestTemplate.header("authorization", "Bearer " + value);
                    log.info("[ feign 拦截器 ] 得到token并封装 heard={}", "authorization", "Bearer " + value);
                }
                //其他参数封装成请求体
                else {
                    body.append(name).append("=").append(value).append("&");
                }

            }
        }
        log.info("[ feign 拦截器 ] 封装响应体{},body={}", body.length(),body);
        if (body.length() > 0) {
            //删除最后一个符号  &
            body.deleteCharAt(body.length() - 1);

//            requestTemplate.body(body.toString().getBytes(), Charset.defaultCharset());
            requestTemplate.body(Request.Body.create(body.toString(), Charset.defaultCharset()));
            requestTemplate.body(body.toString());

        }
    }
}
